package edu.scau.ojforwarder.util;

import edu.scau.ojforwarder.bean.HduError;
import edu.scau.ojforwarder.bean.HduStatus;
import edu.scau.ojforwarder.bean.HduSubmission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

@Component
public class HduSubmitTask extends Thread {

    @Autowired
    private HduStatusManager statusManager;

    @Autowired
    private HduClient hduClient;

    @Autowired
    private HduStatusTask hduStatusTask;

    private final LinkedBlockingQueue<HduSubmission> submissionQueue = new LinkedBlockingQueue<>();
    private Logger logger = LoggerFactory.getLogger(HduSubmitTask.class);

    public HduSubmitTask() {
        start();
    }

    @Override
    public void run() {
        while (true) {
            try {
                HduSubmission submission = submissionQueue.take(); // 当列表为空时，会阻塞至列表非空
                String submissionId = submission.getSubmissionId();
                try {
                    List<HduStatus> statusList;
                    synchronized (hduClient) {
                        statusList = hduClient.getStatus(submission.getCid(), true, false);
                        HduStatus preStatus = null;
                        if (!statusList.isEmpty())
                            preStatus = statusList.get(0);
                        hduClient.submit(submission);
                        statusList = hduClient.getStatus(submission.getCid(), true, false);
                        if (statusList.size() == 0 ||
                                preStatus != null && statusList.get(0).getRunId().equals(preStatus.getRunId()))
                            throw new ErrorException(HduError.NOT_IN_RUNNING_TIME);
                    }
                    statusManager.addAssociation(statusList.get(0).getRunId(), submissionId);
                    statusManager.updateStatus(statusList);
                } catch (Exception e) {
                    if (e instanceof ErrorException) {
                        if (((ErrorException) e).getError() == HduError.CONNECTION_ERROR)
                            submissionQueue.put(submission);
                        else
                            statusManager.setError(submissionId, ((ErrorException) e).getError());
                    } else {
                        logger.error("HDU提交失败！", e);
                        statusManager.setError(submissionId, HduError.OTHER_SUBMIT_EROOR);
                    }
                }
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    public String addSubmission(HduSubmission submission) {
        String submissionId = Long.toString(System.currentTimeMillis()) + (int)(Math.random() * 1000);
        submission.setSubmissionId(submissionId);
        HduStatus status = new HduStatus(submission.getCid());
        status.setProId(submission.getProblemid());
        statusManager.addStatus(submissionId, status);
        try {
            submissionQueue.put(submission);
        } catch (InterruptedException e) {
            logger.error(e.getMessage(), e);
            statusManager.setError(submissionId, HduError.OTHER_SUBMIT_EROOR);
        }
        hduStatusTask.addSubmission(submissionId, submission.getCallback());
        return submissionId;
    }
}
